<?php
/**
 * // +----------------------------------------------------------------------
 * //            -------------------------
 * //           /   / ------------------\  \
 * //                                          \  \
 * //                                           /  /
 * //          /  /  ------------------- /  /
 * //        /  /  ----------------------
 * //      /  /
 * //      \  \
 * //        \  \  ------------------ /  /
 * //          \  \--------------------/
 * // +----------------------------------------------------------------------
 * // | Copyright (c) 2016 Sage  All rights reserved.
 * // +----------------------------------------------------------------------
 * // | Author: Sage
 * // +----------------------------------------------------------------------
 *
 */

/**
 * Created by PhpStorm.
 * User: Sage
 * Date: 2017/12/7
 * Time: 15:35
 */
namespace KysbsUtils\Service;

use KysbsUtils\Config;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
 * 导出服务
 * Class ExportService
 * @package KysbsUtils\Service
 */
class ExportService {

    private $name='导出列表';
    private $title=[];
    private $headerAttach=[];
    private $footerAttach=[];
    private $savePath=Config::TMP_STORAGE;
    private $filename=false;
    private $defaultStyle=[
        'alignment' => [
            'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT,
        ],
        'borders' => [
            'allBorders' => [
                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            ],
        ],
        'font'=>[
            'name'=>'等线'
        ],
    ];
    private $titleStyle = [
        'alignment' => [
            'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
        ],
        'borders' => [
            'allBorders' => [
                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            ],
        ],
        'font'=>[
            'name'=>'等线'
        ],
    ];
    private $dataStyle = [
        'alignment' => [
            'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
        ],
        'font'=>[
            'name'=>'等线'
        ],
        'borders' => [
            'allBorders' => [
                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                'color'=>['argb'=>'ff999999']
            ],
        ]
    ];

    /**
     * 导出为excel
     * @param $title
     * @param $data
     */
    function excel($data=[],$field=false){
        if($field==false || !is_array($field)){
            //直接全部
            $field=array_keys($data[0]);
        }
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('Data');
        $rowIndex=1;
        $colIndex=1;
        $len=1;
        $merges=[];

        $name=$this->name;
        //头部附加信息
        $attach=$this->headerAttach;
        foreach($attach as $info){
            $coordinate=Coordinate::stringFromColumnIndex(1).$rowIndex;
            $sheet->setCellValue($coordinate, "#{$info}");
            array_push($merges,$rowIndex);
            $rowIndex++;
        }

        //分割线
        $coordinate=Coordinate::stringFromColumnIndex(1).$rowIndex;
        $wing=str_repeat('--',15);
        $sheet->setCellValue($coordinate, "#{$wing}{$name}{$wing}");
        array_push($merges,$rowIndex);
        $rowIndex++;

        //标题
        $title=$this->title;
        $start=Coordinate::stringFromColumnIndex(1).$rowIndex;;
        foreach($title as $item){
            $colIndex=1;
            foreach($item as $val){
                $coordinate=Coordinate::stringFromColumnIndex($colIndex).$rowIndex;
                $sheet->setCellValue($coordinate, $val);
                $colIndex++;
            }
            $len=sizeof($item)>$len?sizeof($item):$len;
            $rowIndex++;
        }
        $end=Coordinate::stringFromColumnIndex($colIndex-1).($rowIndex-1);

        $sheet->getStyle("{$start}:{$end}")->applyFromArray($this->titleStyle);
        //数据
        $start=Coordinate::stringFromColumnIndex(1).($rowIndex);
        $index=1;
        foreach($data as $k=>$item){
            $colIndex=1;
            foreach($field as $f){
                $value=$item[$f];
                if($f=='@@id@@'){
                    //加ID序号
                    $value=$index;
                }
                $coordinate=Coordinate::stringFromColumnIndex($colIndex).$rowIndex;
//                $sheet->setCellValue($coordinate, $value);
                $sheet->setCellValueExplicit($coordinate, $value,DataType::TYPE_STRING);
                $colIndex++;
            }
            $index++;
            $rowIndex++;
            unset($data[$k]);
        }
        unset($data);
        $end=Coordinate::stringFromColumnIndex($colIndex-1).($rowIndex-1);
        $sheet->getStyle("{$start}:{$end}")->applyFromArray($this->dataStyle);

        //分割线
        $coordinate=Coordinate::stringFromColumnIndex(1).$rowIndex;
        $sheet->setCellValue($coordinate, "#{$wing}{$name}{$wing}");
        array_push($merges,$rowIndex);
        $rowIndex++;

        //尾部附加信息
        $attach=$this->footerAttach;
        foreach($attach as $info){
            $coordinate=Coordinate::stringFromColumnIndex(1).$rowIndex;
            $sheet->setCellValue($coordinate, "#{$info}");
            array_push($merges,$rowIndex);
            $rowIndex++;
        }

        //合并单元格处理
        foreach($merges as $v){
            $range=Coordinate::stringFromColumnIndex(1).$v.':'.Coordinate::stringFromColumnIndex($len).$v;
            $sheet->mergeCells($range)->getStyle($range)->applyFromArray($this->defaultStyle);
        }

        //生成文件
        $save=$this->filename;
        if($save==false){
            $save=md5(microtime().random_int(1,100000));
        }
        $filename = $this->savePath. DIRECTORY_SEPARATOR. "{$save}.xlsx";
        //保存至xlsx
        $writer = new Xlsx($spreadsheet);
        $writer->save($filename);

//        $filename = $this->savePath. DIRECTORY_SEPARATOR. "{$save}.csv";
//        //保存至csv
//        $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, "Csv");
//        $writer->save($filename);

        $spreadsheet->disconnectWorksheets();
        unset($spreadsheet);
        return $filename;
    }

    /**
     * 设置名称
     * @param $name
     *
     * @return bool
     */
    function setName($name){
        $this->name=$name;
        return true;
    }

    /**
     * 设置标题
     * @param array $title
     *
     * @return bool
     */
    function setTitle($title=[]){
        $this->title=$title;
        return true;
    }

    /**
     * 设置保存目录；路径
     * @param $path
     *
     * @return bool
     */
    function setStorage($path){
        $this->savePath=$path;
        return true;
    }

    function setFileName($filename){

        $this->filename=$filename;
        return true;
    }

    /**
     * 添加头部附加信息
     * @param $attach,可为字符串或字符串的数组
     */
    function addHeaderAttach($attach){
        if(!is_array($attach)){
            $attach=[(string)$attach];
        }

        $this->headerAttach=$attach;
        return true;

    }

    /**
     * 添加尾部附加信息
     * @param $attach,可为字符串或字符串的数组
     */
    function addFooterAttach($attach){
        if(!is_array($attach)){
            $attach=[(string)$attach];
        }
        $this->footerAttach=$attach;
        return true;
    }
}
